﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using King.Engine.Content;
using King.Engine.Core;
using King.Engine.GameObjects;

namespace King.Engine.Components
{
    /// <summary>
    /// Component that displays text on the screen
    /// </summary>
    public class Label : Component
    {

        #region Fields

        private bool _isGUI;

        private string _text;
        private bool _isCentered;
        private Vector2 _locationOffset;

        private SpriteFont _spriteFont;

        #endregion


        #region Constants

        private readonly bool _useParentGuiSetting;
        private readonly float _drawDepth;

        #endregion


        #region Properties

        /// <summary>
        /// The location of the label, relative to the parent
        /// </summary>
        public Vector2 Location;

        /// <summary>
        /// True if the text should be centered around Location.
        /// False if Location represents the top-left point of the text
        /// </summary>
        public bool IsCentered
        {
            get
            {
                return _isCentered;
            }
            set
            {
                _isCentered = value;
                UpdateLocationOffset();
            }
        }

        /// <summary>
        /// The text that is displayed
        /// </summary>
        public string Text
        {
            get
            {
                return _text;
            }
            set
            {
                _text = value;
                UpdateLocationOffset();
            }
        }

        public Color Color;

        override internal protected GameObject Parent
        {
            get
            {
                return base.Parent;
            }

            internal set
            {
                base.Parent = value;
                if (_useParentGuiSetting)
                {
                    _isGUI = Parent.IsGUI;
                }
            }

        }

        #endregion


        #region Constructor
        
        /// <summary>
        /// Crate a label. The isGUI field will match that of the parent
        /// </summary>
        /// <param name="spriteFontName">The name of the label's SpriteFont</param>
        /// <param name="drawDepth">The draw depth of the label</param>
        public Label(string spriteFontName, float drawDepth)
            :this(ContentLoader.Get<SpriteFont>(spriteFontName), drawDepth)
        {
            _useParentGuiSetting = true;
        }

        /// <summary>
        /// Crate a label.
        /// </summary>
        /// <param name="spriteFontName">The name of the label's SpriteFont</param>
        /// <param name="drawDepth">The draw depth of the label</param>
        /// <param name="isGUI">True if this should be drawn as a GUI element</param>
        public Label(string spriteFontName, float drawDepth, bool isGUI)
            : this(ContentLoader.Get<SpriteFont>(spriteFontName), drawDepth)
        {
            _isGUI = isGUI;
            _useParentGuiSetting = false;
        }

        internal Label(SpriteFont spriteFont, float drawDepth)
        {
            _spriteFont = spriteFont;
            _drawDepth = drawDepth;

            this.Color = Color.White;
            this.Text = string.Empty;
        }

        #endregion


        #region Public Methods

        public override void Draw()
        {
            if (String.IsNullOrWhiteSpace(Text))
            {
                return;
            }

            Screen.DrawString(_isGUI, _spriteFont, Text, Parent.Location + Location + _locationOffset, this.Color, 0f, Vector2.Zero, 1f, SpriteEffects.None, _drawDepth);
        }

        #endregion


        #region Private Methods

        private void UpdateLocationOffset()
        {
            if (this.IsCentered)
            {
                Vector2 textSize = _spriteFont.MeasureString(this.Text);
                _locationOffset = -textSize / 2;
            }
            else
            {
                _locationOffset = Vector2.Zero;
            }
        }

        #endregion

    }
}
